<?php
/**
 * Created by PhpStorm.
 * User: jianhe
 * Date: 2018/1/23
 * Time: 14:00
 */
namespace App\Services\Cart;

use App\Services\Bonus\BonusService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\Validator;
use App\Repositories\Cart\CartRepository;
use App\Repositories\Cart\FavourableActivityRepository;
use App\Repositories\Goods\GoodsRepository;
use App\Repositories\Users\UsersRepository;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;

/**
 * Class CartService
 * @package App\Services
 */
class CartService
{
    protected $cartRepository;
    protected $favourableActivityRepository;
    protected $goodsRepository;
    protected $usersRepository;
    protected $bonusService;


    public function __construct(CartRepository $cartRepository,FavourableActivityRepository $favourableActivityRepository,GoodsRepository $goodsRepository,UsersRepository $usersRepository,BonusService $bonusService)
    {
        $this->cartRepository=$cartRepository;
        $this->favourableActivityRepository=$favourableActivityRepository;
        $this->goodsRepository=$goodsRepository;
        $this->usersRepository=$usersRepository;
        $this->bonusService=$bonusService;
    }

    /**
     * @var void 商品列表
     */
    private $GoodsArray;

    /**
     * @var void 可参与活动
     */
    private $ActivityArray;

    private $user_id;

    private $userRank;


    /**
     * @role 增加商品数量
     * @author Jianhe
     * @param $goods_id
     * @param $act_id
     * @param $giving
     * @param $num
     * @param int $user_id
     * @return array
     */
    public function increase($goods_id,$act_id,$giving,$num,$user_id){

        $data=compact('goods_id','act_id','giving','num','user_id');
        $validator = Validator($data, [
            'goods_id' => 'required|numeric|min:1',
            'act_id' => 'required|numeric|min:0',
            'giving' => 'required|numeric|min:0|max:2',
            'num' => 'required|numeric|min:1',
            'user_id' => 'required|numeric|min:1'
        ]);
        if ($validator->fails()) {
            throw new PreconditionFailedHttpException(428,"参数错误");
        }

        //从缓存载入购物车信息
        $this->loadCartInfoInCache($user_id);
        
        $goods_code=$this->GoodsCode($goods_id,$act_id,$giving);
        if($this->checkGoodsCodeExist($goods_code)){
            //如果存在则+数量
            $goodsOb=$this->GoodsArray[$goods_code];
            if($this->checkGoodsStockIsEnough($goodsOb,$num)){
                $reNum=$goodsOb->increase($num);
                $this->cartRepository->updateGoods(['goods_number'=>$reNum],$goodsOb->getRecId());
            }
        }else{
            //如果不存在购物车添加商品
            $goods=$this->goodsRepository->getGoodsByIds([$goods_id])[0];

            $goods['giving']=$giving;
            $goods['num']=$num;
            $goods['act_id']=$act_id;
            $goods['goods_price']=$goods['shop_price'];
            $goods['goods_attr']="";
            $goods['goods_attr_id']="";
            $goods['expiration_date']=0;

            $this->addGoods($goods,$user_id);
        }
        
        //购物车信息保存到缓存
        $this->saveCartInfoToCache($user_id);
        
        return true;
    }

    /**
     * @role 减少商品数量
     * @author Jianhe
     * @param $goods_id
     * @param $act_id
     * @param $giving
     * @param $num
     * @param $user_id
     * @return array|bool
     */
    public function reduce($goods_id,$act_id,$giving,$num,$user_id){
                $data=compact('goods_id','act_id','giving','num','user_id');
                $validator = Validator($data, [
                    'goods_id' => 'required|numeric|min:1',
                    'act_id' => 'required|numeric|min:0',
                    'giving' => 'required|numeric|min:0|max:2',
                    'num' => 'required|numeric|min:1',
                    'user_id' => 'required|numeric|min:1'
                ]);
                if ($validator->fails()) {
                    throw new PreconditionFailedHttpException(428,"参数错误");
                }

                //从缓存载入购物车信息
                $this->loadCartInfoInCache($user_id);

                $goods_code=$this->GoodsCode($goods_id,$act_id,$giving);
                if(!$this->checkGoodsCodeExist($goods_code)){
                    return false;
                }
                $goodsOb=$this->GoodsArray[$goods_code];
                if($goodsOb->getCurrentNumber()>$num){
                    //如果存在则-数量
                    $reNum=$goodsOb->reduce($num);

                    //修改数据表数量
                    $this->cartRepository->updateGoods(['goods_number'=>$reNum],$goodsOb->getRecId());
                }else{
                    //删除商品
                    $this->deleteGoods($goods_code,$giving);


                }

        //购物车信息保存到缓存
        $this->saveCartInfoToCache($user_id);

        return true;
    }

    /**
     * @role 选中/取消 商品
     * @author Jianhe
     * @param $goods_id
     * @param $act_id
     * @param $giving
     * @param $isCheck
     * @param $user_id
     * @return array|bool
     */
    public function setCheck($goods_id,$act_id,$giving,$isCheck,$user_id){
        $data=compact('goods_id','act_id','giving','isCheck','user_id');
        $validator = Validator($data, [
            'goods_id' => 'required|numeric|min:1',
            'act_id' => 'required|numeric|min:0',
            'giving' => 'required|numeric|min:0|max:2',
            'isCheck' => 'required|numeric|min:0|max:1',
            'user_id' => 'required|numeric|min:1'
        ]);
        if ($validator->fails()) {
            throw new PreconditionFailedHttpException(428,"参数错误");
        }

        //从缓存载入购物车信息
        $this->loadCartInfoInCache($user_id);
        
        $goods_code=$this->GoodsCode($goods_id,$act_id,$giving);
        if(!$this->checkGoodsCodeExist($goods_code)){
            return false;
        }
        $goodsOb=$this->GoodsArray[$goods_code];
        $goodsOb->setIsCheck($isCheck);
        if($isCheck==1 && $goodsOb->getIsCheck==0){
            //选中
            $goods=array();
            $goods['cat_id']=$goodsOb->getCatId();
            $goods['brand_id']=$goodsOb->getBrandId();
            $goods['goods_id']=$goodsOb->getGoodsId();
            $this->goodsAddActivity($goods,$this->userRank,$goodsOb);
        }else if($isCheck==0 && $goodsOb->getIsCheck==1){
            //取消选中
            $this->goodsCancelActivity($goods_code,$giving);
        }

        //修改数据表选中状态
        $this->cartRepository->updateGoods(['is_check'=>$isCheck],$goodsOb->getRecId());

        //购物车信息保存到缓存
        $this->saveCartInfoToCache($user_id);

        return true;
    }

    /**
     * @role 商品切换活动
     * @author Jianhe
     * @param $goods_id
     * @param $act_id
     * @param $giving
     * @param $act_id
     * @param $user_id
     * @return array|bool
     */
    public function GoodsSwitchingActivity($goods_id,$act_id,$giving,$user_id){
        $data=compact('goods_id','act_id','giving','user_id');
        $validator = Validator($data, [
            'goods_id' => 'required|numeric|min:1',
            'act_id' => 'required|numeric|min:0',
            'giving' => 'required|numeric|min:0|max:2',
            'user_id' => 'required|numeric|min:1'
        ]);
        if ($validator->fails()) {
            throw new PreconditionFailedHttpException(428,"参数错误");
        }

        //从缓存载入购物车信息
        $this->loadCartInfoInCache($user_id);
        
        $goods_code=$this->GoodsCode($goods_id,$act_id,$giving);
        if(!$this->checkGoodsCodeExist($goods_code)){
            return false;
        }
        $goodsOb=$this->GoodsArray[$goods_code];
        //取消当前活动
        $this->goodsCancelActivity($goods_code,$giving);

        //赋值切换的活动
        $goods=array();
        $goods['cat_id']=$goodsOb->getCatId();
        $goods['brand_id']=$goodsOb->getBrandId();
        $goods['goods_id']=$goodsOb->getGoodsId();
        $this->goodsAddActivity($goods,$this->userRank,$goodsOb,$act_id);

        //修改数据表选中状态
        $this->cartRepository->updateGoods(['act_id'=>$act_id],$goodsOb->getRecId());

        //购物车信息保存到缓存
        $this->saveCartInfoToCache($user_id);

        return true;
    }

    /**
     * @role 我的购物车
     * @author Jianhe
     * @param $user_id
     * @return array
     */
    public function getMyCart($user_id){
        $data=compact('user_id');
        $validator = Validator($data, [
            'user_id' => 'required|numeric|min:1'
        ]);
        if ($validator->fails()) {
            throw new PreconditionFailedHttpException("参数错误");
        }

        //从数据库重载购物车列表
        $this->loadCartInfoInDataBase($user_id);
        return $this->getInfoFormat();
    }

    /**
     * @role 获取生成订单--商品列表数据
     * @author Jianhe
     * @param $user_id
     * @param $bonus_id
     * @return array
     */
    public function getGoodsForOrder($user_id,$bonus_id=0){
        $data=compact('user_id','bonus_id');
        $validator = Validator($data, [
            'user_id' => 'required|numeric|min:1',
            'bonus_id' => 'numeric'
        ]);
        if ($validator->fails()) {
            throw new PreconditionFailedHttpException(428,"参数错误");
        }
        //从数据库重载购物车列表
        $this->loadCartInfoInDataBase($user_id);
        $cartInfo=array();
        $cartTotal=$this->getInfoFormat();
        $cartInfo['total']=$cartTotal['total'];
        $proportion=0;
        if(!empty($bonus_id)){
            $proportion=$this->getGoodsBonusProportion($bonus_id);
        }

        $goodsList=array();
        $goodsPriceChange=0;
        foreach($this->GoodsArray as $goods){
            $goodsList[]=$goods->getGoodsForOrderFormat($proportion);
            if($goods->price_change()){
                $goodsPriceChange+=1;
            }
        }
        $cartInfo['goods_price_change']=$goodsPriceChange;
        $cartInfo['goods_list']=$goodsList;
        return $cartInfo;

    }

    /**
     * @role 清除提交生成订单的商品
     * @author Jianhe
     * @param $user_id
     * @return bool
     */
    public function clearCartForSubmitOrder($user_id){
        //从数据库重载购物车列表
        $this->loadCartInfoInDataBase($user_id);

        foreach($this->GoodsArray as $key=>$goods){
            if($goods->getIsCheck()==1){
                //删除商品
                $this->deleteGoods($key,$goods->getGiving());
            }
        }
        return true;
    }

    //计算商品红包优惠金额比例
    private function getGoodsBonusProportion($bonus_id){
        $goods_total = 0;
        $bonus_goods_proportion=1;
        $bonus_goods_num=0;
        $bonus=$this->bonusService->getBonusTypeConfig($bonus_id);
        foreach($this->GoodsArray as $goods){
            //赠品、设置为不包含促销
            if($goods->getGiving()==1 || $goods->getGiving()==4 && $bonus['include_promotion']==0){
                continue;
            }
            $flag = false;
            if($bonus['is_limit_buy']==0){
                $flag = true;
            }

            if(!empty($bonus['config'])){
                foreach($bonus['config'] as $cfg_key => $val_cfig){
                    switch ($val_cfig['act_rang']) {
                        case 1:
                            $sub_cate_list = $this->categoryService->getAllSubCateId($val_cfig['cate_id']);

                            if (in_array($goods->getCatId(),$sub_cate_list)) {
                                $flag = true;
                            }
                            break;
                        case 2:
                            if ($val_cfig['brand_id'] == $goods->getBrandId()) {
                                $flag = true;
                            }
                            break;
                        case 3:
                            if ($val_cfig['goods_id'] == $goods->getGoodsId()) {
                                $flag = true;
                            }
                            break;
                    }
                }
            }

            if ($flag) {
                $goods_total += $this->getCurrentNumber() * $this->getCurrentPrice();
                $bonus_goods_num++;
            }
        }

        if($bonus['bonus_discount_type']==2){
            $bonus_goods_proportion = $bonus['type_money']/10;
            //$bonus_money=$goods_total*((10-$bonus['type_money'])/10);;
        }else if($bonus['bonus_discount_type']==1){
            $bonus_goods_total = $goods_total - $bonus['type_money'];
            $bonus_goods_proportion = $bonus_goods_total / $goods_total;
            //$bonus_money=$bonus["type_money"];
        }

        //return array("proportion"=>$bonus_goods_proportion,"money"=>$bonus_money);
        return 1-$bonus_goods_proportion;
        
    }

    //判断商品库存是否足够
    private function checkGoodsStockIsEnough($goods_id,$num=0){
        $goodsNumTotal=0;
        $GoodsStock=0;
        foreach($this->GoodsArray as $goods){
            $goodsNumTotal+=$goods->getCurrentNumber();
            $GoodsStock=$goods->getGoodsStock();
        }
        $goodsNumTotal+=$num;
        if($GoodsStock<$goodsNumTotal){
            return false;
        }
        return true;
    }

    /**
     * @role 格式化购物车列表-输出信息
     * @author Jianhe
     * @return array
     */
    private function getInfoFormat(){

        
        $list=array();
        $out_stock_total=array(
            'total_number'=>0,
            'goods_price'=>0,
            'market_price'=>0,
            'shop_price'=>0,
            'total_vip_price'=>0,
            'real_goods_count'=>0,
            'virtual_goods_count'=>0,
            'goods_amount'=>0,
        );
        $cart_total=array(
            'goods_price'=>0,
            'market_price'=>0,
            'total_vip_price'=>0,
            'shop_price'=>0,
            'total_number'=>0,
            'cart_total_amount'=>0,
            'cart_total_number'=>0,
            'real_goods_count'=>0,
            'virtual_goods_count'=>0,
            'reduced_price_goods_total_num'=>0,
            'discount'=>0
        );

        //活动列表
        $list['favourable_list']=array();
        if(!empty($this->ActivityArray)){
            foreach($this->ActivityArray as $activity){
                $list['favourable_list'][]=$activity->getActivityFormat();
            }
        }

        //商品列表
        $list['list']=array();

        //*活动商品
        $list['list']['favourable_goods']=array();
        if(!empty($this->ActivityArray)){
            foreach($this->ActivityArray as $activity){
                if($activity->getParticipateNum()>0){
                    $ActivityWithGoods=$activity->getActivityWithGoodsFormat();
                    $list['list']['favourable_goods'][]=$ActivityWithGoods;

                    //统计活动折扣金额
                    $cart_total['discount']+=$ActivityWithGoods['discount'];
                }
            }
        }

        //*普通商品
        $list['list']['normal_goods']=array();
        //缺货商品列表
        $list['out_stock_list']=array();

        foreach($this->GoodsArray as $goods){

            if($this->checkGoodsStockIsEnough($goods->getGoodsId())){
                //库存足够--普通商品-->再筛选出未参加活动的商品
                if(empty($goods->getCurrentAct())){
                    $list['list']['normal_goods'][]=$goods->getGoodsFormat();
                }

                if($goods->getIsCheck()==1){
                    $cart_total['goods_price'] += $goods->getCurrentPrice()*$goods->getCurrentNumber();
                    $cart_total['market_price']+= $goods->getMarketPrice()*$goods->getCurrentNumber();
                    $cart_total['total_vip_price'] += $goods->getVipPrice()*$goods->getCurrentNumber();
                    $cart_total['shop_price'] += $goods->getGoodsPrice()*$goods->getCurrentNumber();
                    $cart_total['total_number'] += $goods->getCurrentNumber();
                }

                $cart_total['cart_total_amount']+=$goods->getCurrentPrice()*$goods->getCurrentNumber();
                $cart_total['cart_total_number']+=$goods->getCurrentNumber();
                if($goods->getIsReal()==1){
                    $cart_total['real_goods_count']+=1;
                }else{
                    $cart_total['virtual_goods_count']+=1;
                }

                if($goods->getGoodsPrice()<$goods->getAddPrice()){
                    $cart_total['reduced_price_goods_total_num']+=1;
                }

            }else{
                //库存不足--缺货商品
                $list['out_stock_list'][]=$goods->getGoodsFormat();

                //统计购物车中缺货商品数量以及金额
                $out_stock_total['total_number']+= $goods->getCurrentNumber();
                $out_stock_total['goods_price'] += $goods->getCurrentPrice()*$goods->getCurrentNumber();
                $out_stock_total['market_price'] += $goods->getMarketPrice()*$goods->getCurrentNumber();
                $out_stock_total['shop_price'] += $goods->getGoodsPrice()*$goods->getCurrentNumber();
                $out_stock_total['total_vip_price'] += $goods->getVipPrice()*$goods->getCurrentNumber();
                $goods->getIsReal()==1?$out_stock_total['real_goods_count']+=1:$out_stock_total['virtual_goods_count']+=1;

            }
        }

        //缺货商品统计信息
        $out_stock_total['goods_amount'] = $out_stock_total['goods_price'];
        $out_stock_total['saving_format'] = price_format($out_stock_total['market_price'] - $out_stock_total['goods_price'], false);
        if ($out_stock_total['market_price'] > 0) {
            $out_stock_total['save_rate'] = $out_stock_total['market_price'] ? round(($out_stock_total['market_price'] - $out_stock_total['goods_price']) * 100 / $out_stock_total['market_price']) . '%' : 0;
        }
        $out_stock_total['goods_price_format'] = price_format($out_stock_total['goods_price'], false);
        $out_stock_total['market_price_format'] = price_format($out_stock_total['market_price'], false);
        $list['out_stock_total']=$out_stock_total;

        //购物车统计信息
        $cart_total['goods_amount'] = get_price($cart_total['goods_price']-$cart_total['discount']);
        $cart_total['goods_amount_format'] = price_format($cart_total['goods_amount'], false);
        $cart_total['goods_price'] =  $cart_total['goods_amount'];
        $cart_total['goods_price_format'] = price_format($cart_total['goods_price'], false);
        $cart_total['market_price_format'] = price_format($cart_total['market_price'], false);
        $cart_total['total_vip_price'] = get_price($cart_total['total_vip_price']-$cart_total['discount']);
        $cart_total['total_vip_price_format'] = price_format($cart_total['total_vip_price'], false);
        $cart_total['saving'] = get_price($cart_total['market_price'] - $cart_total['goods_amount']);
        $cart_total['saving_format'] = price_format($cart_total['saving'], false);
        $cart_total['save_rate'] = $cart_total['market_price']>0 ? round(($cart_total['market_price'] - $cart_total['goods_amount']) * 100 / $cart_total['market_price']) . '%' : 0;
        $cart_total['vip_saving'] = get_price($cart_total['market_price'] - $cart_total['total_vip_price']);
        $cart_total['vip_saving_format'] = price_format($cart_total['vip_saving'], false);
        $cart_total['vip_save_rate'] = $cart_total['market_price']>0 ? round(($cart_total['market_price'] - $cart_total['vip_saving']) * 100 / $cart_total['market_price']) . '%' : 0;
        $cart_total['derivative_price'] = get_price($cart_total['goods_amount']-$cart_total['total_vip_price']);
        $cart_total['derivative_price_format'] = price_format($cart_total['derivative_price'], false);
        $list['total']=$cart_total;

        //折扣
        $list['discount']=$cart_total['discount'];

        //是否有缺货商品
        $list['have_out_stock']=count($list['out_stock_list'])>0?1:0;

        return $list;
    }

    /**
     * @role 格式化购物车列表-输出信息--新版
     * @author Jianhe
     * @return array
     */
    private function getInfoFormatNew(){


        $list=array();
        $out_stock_total=array(
            'total_number'=>0,
            'goods_price'=>0,
            'market_price'=>0,
            'shop_price'=>0,
            'total_vip_price'=>0,
            'real_goods_count'=>0,
            'virtual_goods_count'=>0,
            'goods_amount'=>0,
        );
        $cart_total=array(
            'goods_price'=>0,
            'market_price'=>0,
            'total_vip_price'=>0,
            'shop_price'=>0,
            'total_number'=>0,
            'cart_total_amount'=>0,
            'cart_total_number'=>0,
            'real_goods_count'=>0,
            'virtual_goods_count'=>0,
            'reduced_price_goods_total_num'=>0,
            'discount'=>0
        );

        //活动列表
        $list['favourable_list']=array();
        if(!empty($this->ActivityArray)){
            foreach($this->ActivityArray as $activity){
                $list['favourable_list'][]=$activity->getActivityFormat();
            }
        }

        //商品列表
        $list['list']=array();

        //*活动商品
        $list['list']['favourable_goods']=array();
        if(!empty($this->ActivityArray)){
            foreach($this->ActivityArray as $activity){
                if($activity->getParticipateNum()>0){
                    $ActivityWithGoods=$activity->getActivityWithGoodsFormat();
                    $list['list']['favourable_goods'][]=$ActivityWithGoods;

                    //统计活动折扣金额
                    $cart_total['discount']+=$ActivityWithGoods['discount'];
                }
            }
        }

        //*普通商品
        $list['list']['normal_goods']=array();
        //缺货商品列表
        $list['out_stock_list']=array();

        foreach($this->GoodsArray as $goods){

            if($this->checkGoodsStockIsEnough($goods->getGoodsId())){
                //库存足够--普通商品-->再筛选出未参加活动的商品
                if(empty($goods->getCurrentAct())){
                    $list['list']['normal_goods'][]=$goods->getGoodsFormat();
                }

                if($goods->getIsCheck()==1){
                    $cart_total['goods_price'] += $goods->getCurrentPrice()*$goods->getCurrentNumber();
                    $cart_total['market_price']+= $goods->getMarketPrice()*$goods->getCurrentNumber();
                    $cart_total['total_vip_price'] += $goods->getVipPrice()*$goods->getCurrentNumber();
                    $cart_total['shop_price'] += $goods->getGoodsPrice()*$goods->getCurrentNumber();
                    $cart_total['total_number'] += $goods->getCurrentNumber();
                }

                $cart_total['cart_total_amount']+=$goods->getCurrentPrice()*$goods->getCurrentNumber();
                $cart_total['cart_total_number']+=$goods->getCurrentNumber();
                if($goods->getIsReal()==1){
                    $cart_total['real_goods_count']+=1;
                }else{
                    $cart_total['virtual_goods_count']+=1;
                }

                if($goods->getGoodsPrice()<$goods->getAddPrice()){
                    $cart_total['reduced_price_goods_total_num']+=1;
                }

            }else{
                //库存不足--缺货商品
                $list['out_stock_list'][]=$goods->getGoodsFormat();

                //统计购物车中缺货商品数量以及金额
                $out_stock_total['total_number']+= $goods->getCurrentNumber();
                $out_stock_total['goods_price'] += $goods->getCurrentPrice()*$goods->getCurrentNumber();
                $out_stock_total['market_price'] += $goods->getMarketPrice()*$goods->getCurrentNumber();
                $out_stock_total['shop_price'] += $goods->getGoodsPrice()*$goods->getCurrentNumber();
                $out_stock_total['total_vip_price'] += $goods->getVipPrice()*$goods->getCurrentNumber();
                $goods->getIsReal()==1?$out_stock_total['real_goods_count']+=1:$out_stock_total['virtual_goods_count']+=1;

            }
        }

        //缺货商品统计信息
        $out_stock_total['goods_amount'] = $out_stock_total['goods_price'];
        $out_stock_total['saving_format'] = price_format($out_stock_total['market_price'] - $out_stock_total['goods_price'], false);
        if ($out_stock_total['market_price'] > 0) {
            $out_stock_total['save_rate'] = $out_stock_total['market_price'] ? round(($out_stock_total['market_price'] - $out_stock_total['goods_price']) * 100 / $out_stock_total['market_price']) . '%' : 0;
        }
        $out_stock_total['goods_price_format'] = price_format($out_stock_total['goods_price'], false);
        $out_stock_total['market_price_format'] = price_format($out_stock_total['market_price'], false);
        $list['out_stock_total']=$out_stock_total;

        //购物车统计信息
        $cart_total['goods_amount'] = get_price($cart_total['goods_price']-$cart_total['discount']);
        $cart_total['goods_amount_format'] = price_format($cart_total['goods_amount'], false);
        $cart_total['goods_price'] =  $cart_total['goods_amount'];
        $cart_total['goods_price_format'] = price_format($cart_total['goods_price'], false);
        $cart_total['market_price_format'] = price_format($cart_total['market_price'], false);
        $cart_total['total_vip_price'] = get_price($cart_total['total_vip_price']-$cart_total['discount']);
        $cart_total['total_vip_price_format'] = price_format($cart_total['total_vip_price'], false);
        $cart_total['saving'] = get_price($cart_total['market_price'] - $cart_total['goods_amount']);
        $cart_total['saving_format'] = price_format($cart_total['saving'], false);
        $cart_total['save_rate'] = $cart_total['market_price']>0 ? round(($cart_total['market_price'] - $cart_total['goods_amount']) * 100 / $cart_total['market_price']) . '%' : 0;
        $cart_total['vip_saving'] = get_price($cart_total['market_price']    - $cart_total['total_vip_price']);
        $cart_total['vip_saving_format'] = price_format($cart_total['vip_saving'], false);
        $cart_total['vip_save_rate'] = $cart_total['market_price']>0 ? round(($cart_total['market_price'] - $cart_total['vip_saving']) * 100 / $cart_total['market_price']) . '%' : 0;
        $cart_total['derivative_price'] = get_price($cart_total['goods_amount']-$cart_total['total_vip_price']);
        $cart_total['derivative_price_format'] = price_format($cart_total['derivative_price'], false);
        $list['total']=$cart_total;

        //折扣
        $list['discount']=$cart_total['discount'];

        //是否有缺货商品
        $list['have_out_stock']=count($list['out_stock_list'])>0?1:0;

        return $list;
    }


    /**
     * @role 商品唯一标识
     * @author Jianhe
     * @param $goods_id
     * @param $act_id
     * @param $giving
     * @return string
     */
    private function GoodsCode($goods_id,$act_id,$giving){
        return $goods_id.'_'.$act_id.'_'.$giving;
    }

    /**
     * @role 判断是否添加过
     * @author Jianhe
     * @param $goods_code
     * @return bool
     */
    private function checkGoodsCodeExist($goods_code){
        if(empty($this->GoodsArray) || !array_key_exists($goods_code,$this->GoodsArray)){
            return false;
        }
        return true;
    }

    /**
     * @role 校验是否满足条件||重置活动--赠品换购--折扣
     * @author Jianhe
     * @param $activity
     */
    private function resetActivityIsSatisfies($activity){
        $Gift=$activity->resetIsSatisfies();
        if(!empty($Gift['remove'])){
            //删除赠品换购
            foreach($Gift['remove'] as $goodsCode){

                //数据表删除商品
                $this->cartRepository->deleteGoods($this->GoodsArray[$goodsCode]->getRecId());
                unset($this->GoodsArray[$goodsCode]);
            }
        }
        if(isset($Gift['add']['goods_id'])){
            //添加单一赠品
            $goods=$this->goodsRepository->findGoodsInfo($Gift['add']['goods_id']);
            $goods['giving']=1;
            $goods['num']=1;
            $goods['goods_stock']=$Gift['add']['goods_stock'];
            $goods['act_id']=$activity->getActId();
            $this->addGoods($goods,$this->user_id);
        }

        if(isset($Gift["setNum"]["rec_id"])){
            //买一赠一累加
            //修改数据表赠品数量
            $this->cartRepository->updateGoods(['goods_number'=>$Gift["setNum"]["num"]],$Gift["setNum"]["rec_id"]);
        }
    }

    /**
     * @role 商品添加活动信息
     * @author Jianhe
     * @param $goods
     * @param $userRank
     * @param $goodsOb
     * @return bool
     */
    private function goodsAddActivity($goods,$userRank,$goodsOb,$act_id=0){
        //获取可参与的活动
        $eligibleAct=$this->favourableActivityRepository->getGoodsActivity($goods,$userRank);

        $eligibleActArray=array();
        foreach($eligibleAct as $item){
            $activity=new ActivityService($item);
            if(empty($this->ActivityArray) || !array_key_exists($item->act_id,$this->ActivityArray)){
                //格式化赠品换购列表
                $giftGoods=array();
                foreach($activity->getGiftGoodsArray() as $goodsItem){
                    $giftGoodsInfo=array();
                    $goodsInfo=$this->goodsRepository->getGoodsByIds([$goodsItem['id']])[0];
                    $giftGoodsInfo['id']=$goodsInfo->goods_id;
                    $giftGoodsInfo['name']=$goodsInfo->goods_name;
                    $giftGoodsInfo['price']=$goodsItem['price'];
                    $giftGoodsInfo['spec_unit']=$goodsInfo->spec_unit;
                    $giftGoodsInfo['spec_value']=$goodsInfo->spec_value;
                    $giftGoodsInfo['goods_img']=$goodsInfo->goods_img;
                    $giftGoodsInfo['goods_price']=$goodsInfo->goods_price;
                    //接入库存..............
                    $giftGoodsInfo['goods_stock']=23;
                }
                $activity->setGiftGoodsArray($giftGoods);

                unset($giftGoods);
            }

            $eligibleActArray[$item->act_id]=$activity;


            //该活动可参与商品数+1
            $activity->canInc();
            $this->ActivityArray[$item->act_id]=$activity;
        }



        if(!empty($eligibleActArray)) {
            $currentAct=reset($eligibleActArray);
            if(!empty($act_id) && isset($this->ActivityArray[$act_id])){
                $currentAct=$this->ActivityArray[$act_id];
            }

            $goodsOb->setEligibleActArray($eligibleActArray);
            $goodsOb->setCurrentAct($currentAct);
            $currentAct->addGoods($goodsOb);
            $currentAct->inc();

            //重新校验活动是否满足条件
            $this->resetActivityIsSatisfies($currentAct);
        }

        return true;
    }

    /**
     * @role 加入购物车
     * @author Jianhe
     * @param $goods
     * @param $user_id
     * @param int $rec_id
     * @return bool
     */
    private function addGoods($goods,$user_id,$rec_id=0)
    {
        if(empty($user_id)){
            return false;
        }
        $this->user_id=$user_id;
        $goods_code=$this->GoodsCode($goods['goods_id'],$goods['act_id'],$goods['giving']);
        if(!empty($this->GoodsArray) && array_key_exists($goods_code,$this->GoodsArray)){
            return false;
        }
        
        $goods['old_goods_price']=0;
        if(!empty($rec_id)){
            $goods['old_goods_price']=$goods['goods_price'];
        }

        //获取会员等级
        if(empty($this->userRank)){
            $this->userRank=$this->usersRepository->getUserRankByUid($user_id);
        }

        //获取商品会员价格
        $goodsMemberPrice=$this->goodsRepository->findGoodsRankPrice($goods['goods_id'],$this->userRank);
        if(!empty($goodsMemberPrice)){
            $goods['goods_price']=$goodsMemberPrice;
        }

        $goodsVipPrice=$this->goodsRepository->findGoodsRankPrice($goods['goods_id'],2);
        if(!empty($goodsVipPrice)){
            $goods['vip_price']=$goodsVipPrice;
        }
        //接入库存..............
        if(!isset($goods['goods_stock'])){
            $goods['goods_stock']=23;
        }
        //接入促销............ 重载$goods['goods_price']、$goods['vip_price']、$goods['isPromote'] call::Jerry

        $goodsOb=new CartGoodsService($goods);
        $this->GoodsArray[$goods_code]=$goodsOb;

        //插入数据库
        if(empty($rec_id)){
            $goodsInfo=array();
            $goodsInfo['user_id']=$this->user_id;
            $goodsInfo['goods_id']=$goods['goods_id'];
            $goodsInfo['goods_sn']=$goods['goods_sn'];
            $goodsInfo['goods_name']=$goods['goods_name'];
            $goodsInfo['market_price']=$goods['market_price'];
            $goodsInfo['goods_price']=$goods['goods_price'];
            $goodsInfo['goods_number']=$goods['num'];
            $goodsInfo['goods_attr']=$goods['goods_attr'];
            $goodsInfo['is_real']=$goods['is_real'];
            $goodsInfo['goods_attr_id']=$goods['goods_attr_id'];
            $goodsInfo['is_presell']=$goods['is_presell'];
            $goodsInfo['act_id']=$goods['act_id'];
            $goodsInfo['giving']=$goods['giving'];
            $goodsInfo['is_check']=1;
            $goodsInfo['expiration_date']=$goods['expiration_date'];

            $rec_id=$this->cartRepository->addGoods($goodsInfo);
        }else{
            $this->cartRepository->updateGoods(['goods_price'=>$goods['goods_price']],$rec_id);
        }

        $goodsOb->setRecId($rec_id);

        $this->goodsAddActivity($goods,$this->userRank,$goodsOb);


    }

    /**
     * @role 商品取消活动相关信息
     * @author Jianhe
     * @param $goods_code
     * @param $giving
     * @return bool
     */
    private function goodsCancelActivity($goods_code,$giving){
        if($giving!=0){
            return false;
        }

        $EligibleActArray=$this->GoodsArray[$goods_code]->getEligibleActArray();
        if(!empty($EligibleActArray)){
            foreach($EligibleActArray as $key=>$item){
                //该商品的参与-1
                $itemAct=$item;
                $itemAct->canRed();
                //判断是否有商品可以参与该活动，如果没有则删除
                if($itemAct->getParticipateCanNum==0){
                    unset($this->ActivityArray[$key]);

                }
            }
            $CurrentAct=$this->GoodsArray[$goods_code]->getCurrentAct();
            if(!empty($CurrentAct)){
                //从参与的活动中删除本商品
                $CurrentAct->deleteGoods($this->GoodsArray[$goods_code]);
                //从参与的活动商品的参与数-1
                $CurrentAct->red();
                //重新校验活动是否满足条件
                $this->resetActivityIsSatisfies($CurrentAct);
            }

        }
        return true;
    }

    /**
     * @role 删除商品
     * @author Jianhe
     * @param $goods_code
     * @param $giving
     */
    private function deleteGoods($goods_code,$giving)
    {
        $this->goodsCancelActivity($goods_code,$giving);

        //数据表删除商品
        $this->cartRepository->deleteGoods($this->GoodsArray[$goods_code]->getRecId());
        unset($this->GoodsArray[$goods_code]);
    }

    /**
     * @role 从缓存载入购物车信息
     * @author Jianhe
     * @param $user_id
     */
    private function loadCartInfoInCache($user_id){
        $ActivityArray = Cache::get('cart_info_activity_array_'.$user_id);
        $GoodsArray = Cache::get('cart_info_goods_array_'.$user_id);
        $userRank = Cache::get('cart_info_user_rank_'.$user_id);
        $this->ActivityArray=unserialize($ActivityArray);
        $this->GoodsArray=unserialize($GoodsArray);
        $this->user_id=$user_id;
        $this->userRank=unserialize($userRank);
    }

    /**
     * @role 购物车信息保存到缓存
     * @author Jianhe
     * @param $user_id
     */
    private function saveCartInfoToCache($user_id){
        Cache::forever('cart_info_activity_array_'.$user_id,serialize($this->ActivityArray));
        Cache::forever('cart_info_goods_array_'.$user_id,serialize($this->GoodsArray));
        Cache::forever('cart_info_user_rank_'.$user_id,serialize($this->userRank));
    }

    /**
     * @role 清空缓存
     * @author Jianhe
     * @param $user_id
     */
    private function unsetCache($user_id){
        $this->ActivityArray=array();
        $this->GoodsArray=array();
        $this->user_id=null;
        $this->userRank=null;
        $this->saveCartInfoToCache($user_id);
    }

    /**
     * @role 从数据库重载购物车列表
     * @author Jianhe
     * @param $user_id
     */
    private function loadCartInfoInDataBase($user_id){
        $this->ActivityArray=array();
        $this->GoodsArray=array();
        $this->user_id=null;
        $this->userRank=null;
        
        $userCart=$this->cartRepository->getByUserId($user_id);

        foreach($userCart as $cartGoods){
            //如果不存在购物车添加商品
            $goods['rec_id']=$cartGoods->rec_id;
            $goods['giving']=$cartGoods->giving;
            $goods['num']=$cartGoods->goods_number;
            $goods['goods_price']=$cartGoods->shop_price;
            $goods['brand_id']=$cartGoods->brand_id;
            $goods['cat_id']=$cartGoods->cat_id;
            $goods['goods_attr']="";
            $goods['goods_attr_id']=0;
            $goods['goods_id']=$cartGoods->goods_id;
            $goods['goods_sn']=$cartGoods->goods_sn;
            $goods['goods_name']=$cartGoods->goods_name;
            $goods['market_price']=$cartGoods->market_price;
            $goods['num']=$cartGoods->goods_number;
            $goods['is_real']=$cartGoods->is_real;
            $goods['goods_attr_id']=$cartGoods->goods_attr_id;
            $goods['is_presell']=$cartGoods->is_presell;
            $goods['act_id']=$cartGoods->act_id;
            $goods['giving']=$cartGoods->giving;
            $goods['expiration_date']=$cartGoods->expiration_date;
            $goods['goods_weight']=$cartGoods->goods_weight;
            $goods['spec_value']=$cartGoods->spec_value;
            $goods['spec_unit']=$cartGoods->spec_unit;
            $goods['spec_unit']=$cartGoods->spec_unit;
            $goods['delivery_type']=$cartGoods->delivery_type;
            $goods['delivery_cycle']=$cartGoods->delivery_cycle;
            $goods['min_buy_num']=$cartGoods->min_buy_num;
            $goods['goods_img']=$cartGoods->goods_img;
            $goods['goods_brief']=$cartGoods->goods_brief;
            $goods['is_auto_morrow_presell']=$cartGoods->is_auto_morrow_presell;
            $goods['is_buynow']=$cartGoods->is_buynow;
            $goods['is_presell']=$cartGoods->is_presell;
            $goods['goods_thumb']=$cartGoods->goods_thumb;
            $goods['extension_code']=$cartGoods->extension_code;



            $this->addGoods($goods,$user_id,$cartGoods->rec_id);
        }
        $this->saveCartInfoToCache($user_id);
        
    }
}
